package me.flyray.common.context;

import me.flyray.common.constant.CommonConstants;
import me.flyray.common.util.StringHelper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

import static org.junit.Assert.assertEquals;

/**
 * Created by ace on 2017/9/8.
 */
public class BaseContextHandler {

    public static ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<Map<String, Object>>();

    public static void set(String key, Object value) {
        Map<String, Object> map = threadLocal.get();
        if (map == null) {
            map = new HashMap<String, Object>();
            threadLocal.set(map);
        }
        map.put(key, value);
    }

    public static Object get(String key){
        Map<String, Object> map = threadLocal.get();
        if (map == null) {
            map = new HashMap<String, Object>();
            threadLocal.set(map);
        }
        return map.get(key);
    }

    public static String getToken(){
        Object value = get(CommonConstants.CONTEXT_KEY_TOKEN);
        return StringHelper.getObjectValue(value);
    }

    public static String getXId(){
        Object value = get(CommonConstants.CONTEXT_KEY_X_ID);
        return StringHelper.getObjectValue(value);
    }

    public static String getXName(){
        Object value = get(CommonConstants.CONTEXT_KEY_NAME);
        return StringHelper.getObjectValue(value);
    }

    public static String getNickname(){
        Object value = get(CommonConstants.CONTEXT_KEY_NICKNAME);
        return StringHelper.getObjectValue(value);
    }

    public static String getPlatformId(){
        Object value = get(CommonConstants.CONTEXT_KEY_PLATFORMID);
        return StringHelper.getObjectValue(value);
    }

    public static String getUserType(){
        Object value = get(CommonConstants.JWT_KEY_USER_TYPE);
        return StringHelper.getObjectValue(value);
    }

    public static void setToken(String token){set(CommonConstants.CONTEXT_KEY_TOKEN,token);}

    public static void setPlatformId(String platformId){
        set(CommonConstants.CONTEXT_KEY_PLATFORMID,platformId);
    }

    public static void setXName(String name){set(CommonConstants.CONTEXT_KEY_NAME,name);}

    public static void setNickname(String name){set(CommonConstants.CONTEXT_KEY_NICKNAME,name);}
    
    public static void setXId(String XId){
        set(CommonConstants.CONTEXT_KEY_X_ID,XId);
    }

    public static void setUserType(String userType){
        set(CommonConstants.JWT_KEY_USER_TYPE,userType);
    }

    private static String returnObjectValue(Object value) {
        return value==null?null:value.toString();
    }

    public static void remove(){
        threadLocal.remove();
    }

    @RunWith(MockitoJUnitRunner.class)
    public static class UnitTest {
        private Logger logger = LoggerFactory.getLogger(UnitTest.class);

        @Test
        public void testSetContextVariable() throws InterruptedException {
            BaseContextHandler.set("test", "main");
            new Thread(()->{
                BaseContextHandler.set("test", "moo");

                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                assertEquals(BaseContextHandler.get("test"), "moo");
                logger.info("thread one done!");
            }).start();
            new Thread(()->{
                BaseContextHandler.set("test", "moo2");
                assertEquals(BaseContextHandler.get("test"), "moo2");
                logger.info("thread two done!");
            }).start();

            Thread.sleep(5000);
            assertEquals(BaseContextHandler.get("test"), "main");
            logger.info("main one done!");
        }

        @Test
        public void testSetUserInfo(){
            BaseContextHandler.setXId("test");
            assertEquals(BaseContextHandler.getXId(), "test");
            BaseContextHandler.setXName("test2");
            assertEquals(BaseContextHandler.getXName(), "test2");
        }
    }
}
